﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using SIGERP_Datos.Properties;
using System.Data;
using SIGERP_Entidades;
using System.Diagnostics;

namespace SIGERP_Datos
{
    public class HndReclamos
    {
        public static List<Reclamo> GetAll()
        {
            DataTable tabla = Conexion.ejecutaSelect("SELECT r.*,ISNULL(reits.cant,0) as cant_reit " +
                " FROM dbo.reclamo AS r " +
                " LEFT JOIN " +
                " (SELECT id_reclamo,COUNT(*) as cant FROM reiteracion GROUP BY id_reclamo ) as reits " +
                " ON r.id_reclamo=reits.id_reclamo ");
            var reclamos = new List<Reclamo>();
            foreach (DataRow dtRow in tabla.Rows)
            {
                Reclamo r = new Reclamo(dtRow);
                r.estadoreclamo = HndEstadosReclamo.getOne(Convert.ToInt32(dtRow["id_estado_reclamo"]));
                r.cant_reiteraciones = Convert.ToInt32(dtRow["cant_reit"]);
                reclamos.Add(r);
            }
            return reclamos;
        }

        public static List<Reclamo> BuscarReclamosPorDepto(Departamento d)
            {
                DataTable tabla = Conexion.ejecutaSelect("SELECT r.*,ISNULL(reits.cant,0) as cant_reit "+
                                    " FROM "+
                                    " dbo.derivacion AS d "+
                                    " INNER JOIN "+
                                     " dbo.reclamo AS r "+
                                     " ON r.id_reclamo=d.id_reclamo "+
                                    " LEFT JOIN  "+
                                    " (SELECT id_reclamo,COUNT(*) as cant FROM reiteracion GROUP BY id_reclamo ) as reits "+
                                    " ON r.id_reclamo=reits.id_reclamo  "+
                                    " WHERE  d.fecha_aceptacion IS NULL AND d.fecha_rechazo IS NULL AND d.id_departamento_destino=" + d.id);  
            var reclamos = new List<Reclamo>();
                foreach (DataRow dtRow in tabla.Rows)
                {
                    Reclamo r = new Reclamo(dtRow);
                    r.estadoreclamo = HndEstadosReclamo.getOne(Convert.ToInt32(dtRow["id_estado_reclamo"]));
                    r.subtiporeclamo = HndSubtipoReclamo.getOne(Convert.ToInt32(dtRow["id_subtipo"]));
                    r.cant_reiteraciones = Convert.ToInt32(dtRow["cant_reit"]);
                    reclamos.Add(r);
                }
                return reclamos;
            }

        public static DataTable GetCantidadPorDeptoEstado(Departamento d)
        {
            DataTable tabla = Conexion.ejecutaSelect("SELECT er.*,ISNULL(cant.cantidad,0) AS cantidad FROM dbo.estado_reclamo AS er "+
                                                     " LEFT JOIN  " +
                                                     " (SELECT  r.id_estado_reclamo as id, COUNT(r.id_reclamo) as cantidad  "+
                                                     " FROM "+
                                                     " dbo.reclamo AS r "+
                                                     " INNER JOIN dbo.estado_reclamo er "+
                                                     " ON r.id_estado_reclamo=er.id_estado_reclamo "+
                                                     " WHERE  r.id_departamento_actual="+d.id+
                                                     " GROUP BY r.id_estado_reclamo) AS cant "+
                                                     " ON er.id_estado_reclamo=cant.id");
            return tabla;
        }

        public static List<Reclamo> buscarReclamosEnCursoPorCliente(Cliente c)
        {
            DataTable tabla = Conexion.ejecutaSelect("SELECT r.*,ISNULL(reits.cant,0) as cant_reit " +
                                    " FROM " +
                                    " dbo.derivacion AS d " +
                                    " INNER JOIN " +
                                     " dbo.reclamo AS r " +
                                     " ON r.id_reclamo=d.id_reclamo " +
                                    " LEFT JOIN  " +
                                    " (SELECT id_reclamo,COUNT(*) as cant FROM reiteracion GROUP BY id_reclamo ) as reits " +
                                    " ON r.id_reclamo=reits.id_reclamo  " +
                                    " WHERE cod_cliente='" + c.cod_cliente + "' and id_estado_reclamo<>1"); // 3 es Finalizado
            var reclamos = new List<Reclamo>();
            foreach (DataRow dtRow in tabla.Rows)
            {
                Reclamo r = new Reclamo(dtRow);
                r.subtiporeclamo = HndSubtipoReclamo.getOne(Convert.ToInt32(dtRow["id_subtipo"]));
                r.estadoreclamo = HndEstadosReclamo.getOne(Convert.ToInt32(dtRow["id_estado_reclamo"]));
                r.cliente = c;
                r.origen = HndOrigenesReclamo.GetOne(Convert.ToInt32(dtRow["id_origen_reclamo"]));
                r.usuario = HndUsuario.getOne(Convert.ToInt32(dtRow["id_usuario"]));
                r.departamento_actual = HndDepartamento.getOne(Convert.ToInt32(dtRow["id_departamento_actual"]));
                r.cant_reiteraciones = Convert.ToInt32(dtRow["cant_reit"]);
                reclamos.Add(r);
            }
            return reclamos;
        }

        public static List<Reclamo> buscarReclamosEnCursoPorClienteWEB(Cliente c)
        {
            DataTable tabla = Conexion.ejecutaSelect("SELECT * FROM reclamo where cod_cliente='" + c.cod_cliente + "'"); 
            var reclamos = new List<Reclamo>();
            foreach (DataRow dtRow in tabla.Rows)
            {
                Reclamo r = new Reclamo(dtRow);
                r.subtiporeclamo = HndSubtipoReclamo.getOne(Convert.ToInt32(dtRow["id_subtipo"]));
                r.estadoreclamo = HndEstadosReclamo.getOne(Convert.ToInt32(dtRow["id_estado_reclamo"]));
                r.cliente = c;
                r.origen = HndOrigenesReclamo.GetOne(Convert.ToInt32(dtRow["id_origen_reclamo"]));
                r.usuario = HndUsuario.getOne(Convert.ToInt32(dtRow["id_usuario"]));
                r.departamento_actual = HndDepartamento.getOne(Convert.ToInt32(dtRow["id_departamento_actual"]));
                reclamos.Add(r);
            }
            return reclamos;
        }

        public static List<Reclamo> buscarReclamosEnCursoPorUsuario(Usuario u)
        {
            DataTable tabla = Conexion.ejecutaSelect("SELECT * FROM dbo.reclamo where id_usuario_actual=" + u.id + " and id_estado_reclamo=2"); // 3 es Finalizado
            var reclamos = new List<Reclamo>();
            foreach (DataRow dtRow in tabla.Rows)
            {
                Reclamo r = new Reclamo(dtRow);
                r.subtiporeclamo = HndSubtipoReclamo.getOne(Convert.ToInt32(dtRow["id_subtipo"]));
                r.estadoreclamo = HndEstadosReclamo.getOne(Convert.ToInt32(dtRow["id_estado_reclamo"]));
                r.cliente = HndClientes.getOne(Convert.ToInt32(dtRow["cod_cliente"]));
                r.origen = HndOrigenesReclamo.GetOne(Convert.ToInt32(dtRow["id_origen_reclamo"]));
                r.usuario = u;
                r.departamento_actual = HndDepartamento.getOne(Convert.ToInt32(dtRow["id_departamento_actual"]));
                reclamos.Add(r);
            }
            return reclamos;
        }

        public static int getCountEnCursoPorUsuario(Usuario u)
        {
            DataTable tabla = Conexion.ejecutaSelect("SELECT COUNT(*) AS cant FROM dbo.reclamo where id_usuario_actual=" + u.id + " and id_estado_reclamo=2"); // 3 es Finalizado
            int cant = 0;
            DataRow dtRow= tabla.Rows[0];
            cant=Convert.ToInt32(dtRow["cant"]);
            //System.Diagnostics.Debug.Write("SELECT COUNT(*) AS cant FROM dbo.reclamo where id_usuario_actual=" + u.id + " and id_estado_reclamo=2");
            
            return cant;
        }

        public static List<Reiteracion> devolverReiteracionesReclamo(Reclamo r)
        {
            DataTable tabla = Conexion.ejecutaSelect("SELECT * FROM dbo.reiteracion where id_reclamo='" + r.id + "'");
            var reiteraciones = new List<Reiteracion>();
            foreach (DataRow dtRow in tabla.Rows)
            {
                Reiteracion rei = new Reiteracion(dtRow);
                rei.reclamo = r;
                reiteraciones.Add(rei);
            }

            return reiteraciones;
        }

        public static void reiterarReclamo(Reiteracion r)
        {
            SqlCommand comando = new SqlCommand();

            comando.CommandText = "INSERT INTO dbo.reiteracion(id_reclamo,fecha_reiteracion, observacion) VALUES (@id_reclamo,GETDATE(),@observacion)";
            comando.Parameters.AddWithValue("@id_reclamo", r.reclamo.id);
            comando.Parameters.AddWithValue("@observacion", r.observacion);
            Conexion.ejecutaComando(comando);
        }

        public static Reclamo GetOne(int id)
        {
            DataTable tabla = Conexion.ejecutaSelect("SELECT r.*,ISNULL(reits.cant,0) as cant_reit "+
                " FROM dbo.reclamo AS r "+
                " LEFT JOIN "+
                " (SELECT id_reclamo,COUNT(*) as cant FROM reiteracion GROUP BY id_reclamo ) as reits "+
                " ON r.id_reclamo=reits.id_reclamo "+
                " WHERE r.id_reclamo=" + id);
            if(tabla.Rows.Count>0){
            DataRow dtRow = tabla.Rows[0];
            Reclamo r = new Reclamo(dtRow);
            r.cant_reiteraciones = Convert.ToInt32(dtRow["cant_reit"]);
            r.estadoreclamo = HndEstadosReclamo.getOne(Convert.ToInt32(dtRow["id_estado_reclamo"]));
            r.cliente = HndClientes.getOne(Convert.ToInt32(dtRow["cod_cliente"]));
            r.origen = HndOrigenesReclamo.GetOne(Convert.ToInt32(dtRow["id_origen_reclamo"]));
            r.usuario = HndUsuario.getOne(Convert.ToInt32(dtRow["id_usuario"]));
            if(dtRow["id_usuario_actual"]!=DBNull.Value) r.usuario_actual = HndUsuario.getOne(Convert.ToInt32(dtRow["id_usuario_actual"]));
            r.departamento_actual = HndDepartamento.getOne(Convert.ToInt32(dtRow["id_departamento_actual"])); 
            r.subtiporeclamo = HndSubtipoReclamo.getOne(Convert.ToInt32(dtRow["id_subtipo"])); 
            return r;
            }else{return null;}
        }

        public static Reclamo Insert(Reclamo reclamo)
        {

            SqlCommand comando = new SqlCommand();
            comando.CommandText = "INSERT INTO dbo.reclamo(fecha_ingreso,descripcion, "+
                " id_origen_reclamo,id_subtipo, id_usuario,cod_cliente,id_estado_reclamo,id_departamento_actual) " +
                " OUTPUT INSERTED.id_reclamo " +
                " VALUES (GETDATE(),@descripcion,@id_origen_reclamo,@id_subtipo, " +
                " @id_usuario,@cod_cliente,@id_estado_reclamo,@id_departamento_actual)";
            

            comando.Parameters.AddWithValue("@descripcion", reclamo.descripcion);
            comando.Parameters.AddWithValue("@id_origen_reclamo", reclamo.origen.id);
            comando.Parameters.AddWithValue("@id_subtipo", reclamo.subtiporeclamo.id);
            comando.Parameters.AddWithValue("@id_usuario", reclamo.usuario.id);
            comando.Parameters.AddWithValue("@cod_cliente", reclamo.cliente.cod_cliente);
            comando.Parameters.AddWithValue("@id_estado_reclamo", 1);
            comando.Parameters.AddWithValue("@id_departamento_actual", reclamo.subtiporeclamo.departamento.id);

            reclamo.id = Conexion.ejecutaTraeId(comando);
            return reclamo;
        }


        public static void Update(Reclamo reclamo)
        {

            SqlCommand comando = new SqlCommand();
            comando.CommandText = "UPDATE dbo.reclamo SET fecha_ingreso=@fecha_ingreso,"+
                "descripcion=@descripcion,id_origen_reclamo=@id_origen_reclamo,"+
                "id_subtipo=@id_subtipo, id_usuario=@id_usuario,cod_cliente=@cod_cliente,"+
                "id_estado_reclamo=@id_estado_reclamo,"+
                "fecha_resolucion=@fecha_resolucion,fecha_tentativa=@fecha_tentativa,"+
                "descripcion_resolucion=@descripcion_resolucion "
                + "WHERE id_reclamo=@id_reclamo";

            comando.Parameters.AddWithValue("@fecha_ingreso", reclamo.descripcion);
            comando.Parameters.AddWithValue("@descripcion", reclamo.descripcion);
            comando.Parameters.AddWithValue("@id_origen_reclamo", reclamo.origen.id);
            comando.Parameters.AddWithValue("@id_subtipo", reclamo.subtiporeclamo.id);
            comando.Parameters.AddWithValue("@id_usuario", reclamo.usuario.id);
            comando.Parameters.AddWithValue("@cod_cliente", reclamo.cliente.cod_cliente);
            comando.Parameters.AddWithValue("@id_estado_reclamo", reclamo.estadoreclamo.id_estado_reclamo);
            comando.Parameters.AddWithValue("@fecha_resolucion", reclamo.fecha_resolucion);
            comando.Parameters.AddWithValue("@fecha_tentativa", reclamo.fecha_tentativa);
            comando.Parameters.AddWithValue("@descripcion_resolucion", reclamo.descripcion);
            comando.Parameters.AddWithValue("@id_reclamo", reclamo.id);
            Conexion.ejecutaComando(comando);
        }

        public static void Delete(Reclamo reclamo)
        {
            SqlCommand comando = new SqlCommand();
            comando.CommandText = "DELETE FROM dbo.reclamo WHERE id_reclamo=@id_reclamo";
            comando.Parameters.AddWithValue("@id_reclamo", reclamo.id);
            Conexion.ejecutaComando(comando);
        }

        public static void PasarAEnCurso(Reclamo reclamo)
        {

            SqlCommand comando = new SqlCommand();
            comando.CommandText = "UPDATE dbo.reclamo SET id_estado_reclamo=2,fecha_tentativa=@fecha_tentativa,id_usuario_actual=@id_usuario_actual WHERE id_reclamo=@id_reclamo";

            comando.Parameters.AddWithValue("@fecha_tentativa", reclamo.fecha_tentativa);
            comando.Parameters.AddWithValue("@id_usuario_actual", reclamo.usuario_actual.id);
            comando.Parameters.AddWithValue("@id_reclamo", reclamo.id);

            Conexion.ejecutaComando(comando);
        }

        public static void ActualizaDeptoActual(Reclamo reclamo)
        {

            SqlCommand comando = new SqlCommand();
            comando.CommandText = "UPDATE dbo.reclamo SET id_departamento_actual=@id_departamento_actual WHERE id_reclamo=@id_reclamo";

            comando.Parameters.AddWithValue("@id_departamento_actual", reclamo.departamento_actual.id);
            comando.Parameters.AddWithValue("@id_reclamo", reclamo.id);

            Conexion.ejecutaComando(comando);
        }

        public static void resolver(Reclamo reclamo)
        {
            SqlCommand comando = new SqlCommand();
            comando.CommandText = "UPDATE dbo.reclamo SET id_estado_reclamo=3, fecha_resolucion=GETDATE(), descripcion_resolucion=@descripcion_resolucion WHERE id_reclamo=@id_reclamo";

            comando.Parameters.AddWithValue("@descripcion_resolucion", reclamo.descripcion_resolucion);
            comando.Parameters.AddWithValue("@id_reclamo", reclamo.id);

            Conexion.ejecutaComando(comando);
        }

        public static List<Reclamo> ConsultaReclamos(int tipo, DateTime? desde,DateTime? hasta,Cliente cliente,Area area,Departamento depto)
        {
            String fecha = "";
            if (tipo == 0) fecha = "fecha_ingreso";
            if (tipo == 1) fecha = "fecha_tentativa";
            if (tipo == 2) fecha = "fecha_resolucion";
 
             SqlCommand comando = new SqlCommand();
            comando.CommandText = "SELECT r.*,ISNULL(reits.cant,0) as cant_reit " +
                " FROM dbo.reclamo AS r " +
                " INNER JOIN departamento d ON r.id_departamento_actual=d.id_departamento " +
                " LEFT JOIN " +
                " (SELECT id_reclamo,COUNT(*) as cant FROM reiteracion GROUP BY id_reclamo ) as reits " +
                " ON r.id_reclamo=reits.id_reclamo " +
                " WHERE 1=1 ";

            if(desde!=null&&hasta!=null)
            comando.CommandText+=" AND r." + fecha + ">=@desde AND r." + fecha + "<= @hasta ";
            
            if(area.id!=0)
                comando.CommandText+=" AND d.id_area= @id_area ";

            if (depto != null&&depto.id!=0)
                comando.CommandText += " AND r.id_departamento_actual= @id_departamento_actual ";

            if (cliente!=null)
                comando.CommandText += " AND r.cod_cliente= @cod_cliente ";

            if (desde != null && hasta != null)
            {
                comando.Parameters.AddWithValue("@desde", ((DateTime)desde).Date);
                comando.Parameters.AddWithValue("@hasta", ((DateTime)hasta).Date);
            }

            if (area.id != 0)
                comando.Parameters.AddWithValue("@id_area", area.id);

            if (depto != null && depto.id != 0)
                comando.Parameters.AddWithValue("@id_departamento_actual", depto.id);

            if (cliente != null)
                comando.Parameters.AddWithValue("@cod_cliente", cliente.cod_cliente);

            DataTable tabla = Conexion.ejecutaSelectCommand(comando);

            var reclamos = new List<Reclamo>();
            foreach (DataRow dtRow in tabla.Rows)
            {
                Reclamo r = new Reclamo(dtRow);
                r.estadoreclamo = HndEstadosReclamo.getOne(Convert.ToInt32(dtRow["id_estado_reclamo"]));
                r.subtiporeclamo = HndSubtipoReclamo.getOne(Convert.ToInt32(dtRow["id_subtipo"]));
                r.cant_reiteraciones = Convert.ToInt32(dtRow["cant_reit"]);
                r.cliente = HndClientes.getOne(Convert.ToInt32(dtRow["cod_cliente"]));
                Debug.Write(dtRow["descripcion"].ToString().Trim());
                if (dtRow["id_usuario_actual"] != DBNull.Value) r.usuario_actual = HndUsuario.getOne(Convert.ToInt32(dtRow["id_usuario_actual"]));
                r.departamento_actual = HndDepartamento.getOne(Convert.ToInt32(dtRow["id_departamento_actual"])); 
                reclamos.Add(r);
            }
            return reclamos;
        }

        public static void ActualizaDeptoyUsuarioActual(Reclamo reclamo)
        {
            SqlCommand comando = new SqlCommand();
            comando.CommandText = "UPDATE dbo.reclamo SET id_departamento_actual=@id_departamento_actual,id_usuario_actual=NULL WHERE id_reclamo=@id_reclamo";

            comando.Parameters.AddWithValue("@id_departamento_actual", reclamo.departamento_actual.id);
            comando.Parameters.AddWithValue("@id_reclamo", reclamo.id);

            Conexion.ejecutaComando(comando);
        }

        public static void AsignarReclamo(Reclamo r)
        {
            SqlCommand comando = new SqlCommand();
            comando.CommandText = "UPDATE dbo.reclamo SET id_usuario_actual=@id_usuario_actual,id_estado_reclamo=2,fecha_tentativa=@fecha_tentativa WHERE id_reclamo=@id_reclamo";

            comando.Parameters.AddWithValue("@id_usuario_actual", r.usuario_actual.id);
            comando.Parameters.AddWithValue("@id_reclamo", r.id);
            comando.Parameters.AddWithValue("@fecha_tentativa", r.fecha_tentativa);

            Conexion.ejecutaComando(comando);
        }
    }
}
